﻿jQuery.fn.extend({
    /*
    * 对表单元素进行赋值
    * params: {
    *  jsonData: json对象
    *  onComplete: 设置完JSON对象属性后所执行的方法
    *  onItemComplete: 每设置完JSON对象的一个根属性后所执行的方法(error, form, name, value)
    * }
    */
    loadJSON: function (args) {

        //设置单个表单项的值
        var setValue = function (name, value) {
            var isarr = $.isArray(value);
            var isobj = false;      //值元素是否为对象形式
            if (isarr && value.length > 0 && typeof value[0] == 'object') {
                isobj = true;
            }
            if (!isarr && typeof value == 'object') {
                isobj = true;
            }

            var els = [];       //根据name找到的多个控件
            var el = null;      //根据name匹配的第一个控件
            //根据数组设置多个值
            if (isarr) {
                //首先查找是否有相应的combo控件
                els = $('[comboname="' + name + '_ID"]');
                if (els.length == 0) {
                    //若无combo类控件，则考虑chooseField的情形
                    els = $('[name="' + name + '_ID"]');
                    if (els.length > 0) {
                        el = els[0];
                        $(el).val(value.joinby(',', 'ID'));
                        $('[name="' + name + '_Name"]').val(value.joinby(',', 'Name'));
                    } else {
                        console.warn('加载表单数据时找不到name为 ' + name + ' 的表单控件。');
                    }
                } else if (els.length == 1) {
                    el = els[0];
                    //针对combo\datebox的情形
                    var ctrlType = getCtrlTypeByClassName(el.className);
                    if (isobj) {
                        $(el)[ctrlType]('setValues', value.select('ID'));
                    } else {
                        $(el)[ctrlType]('setValues', value);
                    }
                } else {
                    if (isobj) {
                        $(els).val(value.select('ID'));
                    } else {
                        $(els).val(value);
                    }
                }
            } else if (isobj) {
                for (var prop in value) {
                    setValue(name + '_' + prop, value[prop]);
                }
            } else {
                els = $.getElsByName(name);
                if (els.length == 0) {
                    //针对combotree的情形
                    els = $('[comboname="' + name + '"]');
                    if (els.length == 0) {
                        console.warn('加载表单数据时找不到name为 ' + name + ' 的表单控件。');
                    } else {
                        el = els[0];
                        var ctrlType = getCtrlTypeByClassName(el.className);
                        $(el)[ctrlType]('setValue', value);
                    }
                } else {
                    el = els[0];
                    //针对combo\datebox的情形
                    if (el.className == 'combo-value') {
                        el = el.parentNode.previousSibling;
                        var ctrlType = getCtrlTypeByClassName(el.className);
                        $(el)[ctrlType]('setValue', value);
                    } else {
                        $(els[0]).val(value);
                    }
                }
            }
        }

        //根据样式推测控件类型
        var getCtrlTypeByClassName = function (className) {
            if (className.indexOf('combotree') > 0) {
                return 'combotree';
            } else if (className.indexOf('combobox') > 0) {
                return 'combobox';
            } else if (className.indexOf('datebox') > 0) {
                return 'datebox';
            } else {
                return 'datetimebox';
            }
        }

        var defaults = { jsonData: { ID: 0 }, onComplete: null, onItemComplete: null };
        args = $.extend({}, defaults, args);

        for (var name in args.jsonData) {
            var value = args.jsonData[name];
            var control = setValue(name, value);
            if (args.onItemComplete) {
                args.onItemComplete.call(control, { name: name, value: value });
            }
        }
        //将对象绑定到form
        this.data('data', args.jsonData);

        // 加载完毕之后初始化自定义的combobox控件（radio,checkbox）
        this.find('.easyui-combobox-yl').each(function () {
            $(this).ylCombobox();
        });
        this.find('.easyui-combogrid-yl').each(function () {
            $(this).combogrid();
        });

        // 加载完毕
        if (args.onComplete) {
            args.onComplete.call(this, args.jsonData);
        }
        return this;
    },

    //将Form中的input元素序列化成服务端可识别的查询字符串
    toQueryString: function () {
        var form = this;
        var items = form.formToArray();                 //获取序列化数组对象（name: "ID", required: false, type: "hidden", value: 26）jquery.form.js扩展
        var inputs = form.find('input');
        //将items的value属性值修改成服务端可识别的值
        for (var i = items.length - 1; i > -1; i--) {
            var item = items[i];
            if (item.value) {
                var input = inputs.filter('[name="' + item.name + '"]').first();
                var tempInput = inputs.filter('[comboname="' + item.name + '"]').first();
                var dataType = input.attr('dataType');
                var comparison = input.attr('comparison');

                //为了兼容easyui生成的控件
                dataType = dataType == null ? tempInput.attr('dataType') : dataType;
                comparison = comparison == null ? tempInput.attr('comparison') : comparison;

                dataType = dataType == null || $.trim(dataType) == '' ? 'String' : dataType;        //不包含数据类型，就用String
                comparison = comparison == null || $.trim(comparison) == '' ? 'Eq' : comparison;    //不包含比较类型，就用Eq
                item.value = dataType + '.' + comparison + '.' + item.value;
            } else {
                //移除没有值的查询参数
                items.splice(i, 1);
            }
        }
        //将数组对象序列化为QueryString
        return $.param(items);
    },

    /*布局处理*/
    //自动适应宽度，要求条件：
    //1、首行的th、td的colSpan值不能大于1；
    //2、表单项名称使用th标签，表单项使用td标签
    //3、需要通过点击按钮来打开选择窗体的选择性字段，使用chooseField样式的DIV
    autoFormLayout: function () {
        var form = this;
        var widths = [];
        var thWidthSum = 0;
        var tdWidthEvg = 0;
        form.find('tr:eq(0)').children().each(function () {
            var item = { owidth: $(this).outerWidth(), width: $(this).width() };
            if (this.tagName == 'TH') {
                thWidthSum += item.owidth;
            }
            widths.push(item);
        });

        tdWidthEvg = (form.width() - thWidthSum) / widths.length * 2;
        var i = 0;
        form.find('tr:eq(0)').children().each(function () {
            if (this.tagName == 'TD') {
                $(this).css('width', tdWidthEvg - 10);
                widths[i].width = tdWidthEvg - 10 - 6;
                widths[i].owidth = tdWidthEvg;
            }
            i++;
        });

        form.find('tr').each(function () {
            var idx = 0;
            $(this).children().each(function () {
                if (this.tagName == 'TH') {
                    idx++;
                } else {
                    //累加列宽计算
                    var width = widths[idx].width;
                    for (var i = 1; i < this.colSpan; i++) {
                        width += widths[idx + i].owidth;
                    }
                    //直接按照父容器宽度计算 
                    //var width = $(this).width() - 6;
                    $(this).find('> input[type="text"]').css('width', width);
                    $(this).find('> textarea').css('width', width);
                    $(this).find('> .combo').css('width', width);
                    $(this).find('> .combo > input').css('width', width - 20);
                    $(this).find('> .chooseField input').css('width', width - 20);
                    var sels = this.getElementsByTagName('select');
                    if (sels.length > 0) {
                        var pnl = $(sels[0]).combobox('panel');
                        pnl.panel({ width: width });
                        var opts = $(sels[0]).combo('options');
                        opts.width = width;
                    }
                    idx += this.colSpan;
                }
            });
        });
    }
});


$.fn.formToJson = function (semantic) {
    var a = this.formToArray(semantic);
    var json = {};
    for (var i = 0; i < a.length; i++) {
        var el = a[i];
        if (json[el.name] != undefined) {
            json[el.name] = json[el.name] + ',' + el.value;
        } else {
            json[el.name] = el.value;
        }
    }
    return json;
}